<template>
  <el-form label-width="90px" label-position="left">
    <el-collapse v-model="activeName">
      <el-collapse-item name="animate" title="动画">
        <div class="collapse-content">
          <el-form-item label="时长" v-if="!isLine">
            <span>{{ activeDuration }}</span>
          </el-form-item>
          <el-form-item label="动画效果" v-if="isLine">
            <el-select
              v-model="store.currentPen.lineAnimateType"
              placeholder="水流"
              @change="handleChangePen('lineAnimateType')"
            >
              <el-option
                v-for="item in lineAnimateTypeOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              >
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="动画线条" v-show="isLine && Number(store.currentPen.lineAnimateType) === 1">
            <el-select
              ref="lineTypeSelect"
              v-model="(store.currentPen as CustomPen).customAnimateLineDash"
              placeholder=""
              @change="handleChangePenLineType"
            >
              <el-option v-for="item in lineStrokeOptions" :key="item.value" :label="' '" :value="item.value">
                <img width="75" :src="item.svg" alt="" />
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="圆点大小" v-show="isLine && Number(store.currentPen.lineAnimateType) === 2">
            <el-input-number
              controls-position="right"
              v-model="store.currentPen.animateDotSize"
              :min="6"
              :step="1"
              placeholder="最小值6"
              @input="handleChangePen('animateDotSize')"
            ></el-input-number>
          </el-form-item>
          <el-form-item
            v-for="meta in isLine ? lineFormMeta.concat(commonFormMeta) : shapeFormMeta.concat(commonFormMeta)"
            :key="meta.key"
            :label="meta.label"
          >
            <el-select
              v-if="meta.type === 'select'"
              v-model="store.currentPen[meta.key]"
              @change="handleChangePen(meta.key)"
              :placeholder="meta.placeholder"
            >
              <el-option v-for="item in meta.options" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
            <el-input
              v-else-if="meta.type === 'input'"
              v-model="store.currentPen[meta.key]"
              @input="handleChangePen(meta.key)"
              :placeholder="meta.placeholder"
            ></el-input>
            <el-input-number
              v-else-if="meta.type === 'input-number'"
              controls-position="right"
              v-model="store.currentPen[meta.key]"
              :min="meta.min"
              :max="meta.max"
              :step="meta.step"
              :placeholder="meta.placeholder"
              @input="handleChangePen(meta.key)"
            ></el-input-number>
            <el-color-picker
              v-else-if="meta.type === 'color-picker'"
              v-model="store.currentPen[meta.key]"
              @change="handleChangePen(meta.key)"
            ></el-color-picker>
            <el-slider
              v-else-if="meta.type === 'slider'"
              v-model="store.currentPen[meta.key]"
              :min="meta.min"
              :max="meta.max"
              size="small"
            />
            <el-switch
              v-else-if="meta.type === 'switch'"
              v-model="store.currentPen[meta.key]"
              @change="handleChangePen(meta.key)"
            ></el-switch>
          </el-form-item>
          <el-button type="primary" icon="VideoPlay" @click="startAnimate">播放</el-button>
          <el-button type="primary" icon="VideoPause" @click="pauseAnimate">暂停</el-button>
          <el-button type="primary" icon="CircleClose" @click="stopAnimate">停止</el-button>
        </div>
      </el-collapse-item>
    </el-collapse>
  </el-form>
</template>

<script setup lang="ts">
  import { useTopologyEditorStore } from '@/stores/modules/topology-editor'
  import { PenType } from '@/components/TopologyEditor/constant'
  import type { Option } from 'element-plus/es/components/select-v2/src/select.types'
  import type { Pen } from '@meta2d/core'
  import type { FormMetaItem } from 'types/editor'
  const store = useTopologyEditorStore()
  const lineDashedSmall = new URL('../assets/svg/line-dashed-small.svg', import.meta.url).href
  const lineDashedLarge = new URL('../assets/svg/line-dashed-large.svg', import.meta.url).href
  const lineDashedDot = new URL('../assets/svg/line-dashed-dot.svg', import.meta.url).href
  declare const window: any
  declare interface CustomPen extends Pen {
    customAnimateLineDash: string
  }

  defineOptions({
    name: 'EditorPropsPenAnimate'
  })

  const activeName = ref(['animate', 'tooltips'])
  const activeDuration = ref()
  const isLine = computed(() => {
    return store.currentPen.type === PenType.Line
  })
  const lineAnimateTypeOptions: Option[] = [
    { value: 0, label: '水流' },
    { value: 1, label: '水珠流动' },
    { value: 2, label: '圆点' }
  ]
  const lineStrokeOptions: Option[] = [
    { value: '5, 5', label: '虚线1', svg: lineDashedSmall },
    { value: '10, 10', label: '虚线2', svg: lineDashedLarge },
    { value: '10, 10, 2, 10', label: '虚线3', svg: lineDashedDot }
  ]
  const lineFormMeta = reactive<FormMetaItem[]>([
    {
      type: 'input-number',
      label: '动画线宽',
      key: 'animateLineWidth',
      min: 0,
      step: 1,
      placeholder: ''
    },
    { type: 'color-picker', label: '动画颜色', key: 'animateColor' },
    {
      type: 'slider',
      label: '动画速度',
      key: 'animateSpan',
      min: 1,
      max: 5
    },
    { type: 'switch', label: '反向流动', key: 'animateReverse' }
  ])
  const shapeFormMeta = reactive<FormMetaItem[]>([
    {
      type: 'select',
      label: '动画效果',
      key: 'animateType',
      options: [
        { value: '', label: '无' },
        { value: 'upDown', label: '上下跳动' },
        { value: 'leftRight', label: '左右跳动' },
        { value: 'heart', label: '心跳' },
        { value: 'success', label: '成功' },
        { value: 'warning', label: '警告' },
        { value: 'error', label: '错误' },
        { value: 'show', label: '炫耀' },
        { value: 'rotate', label: '旋转' }
      ]
    }
  ])
  const commonFormMeta = reactive<FormMetaItem[]>([
    {
      type: 'input-number',
      label: '循环次数',
      key: 'animateCycle',
      min: 1,
      max: Infinity,
      step: 1,
      placeholder: '默认无限循环'
    },
    { type: 'input', label: '下个动画', key: 'nextAnimate', placeholder: 'tag' },
    { type: 'switch', label: '自动播放', key: 'autoPlay' },
    { type: 'switch', label: '保持动画状态', key: 'keepAnimateState' },
    {
      type: 'select',
      label: '线性播放',
      key: 'linear',
      options: [
        { value: true, label: '是' },
        { value: false, label: '否' }
      ]
    }
  ])
  function handleChangePen(propKey: keyof Pen) {
    const propValue = store.currentPen[propKey]
    console.log('set ' + propKey + ' : ' + propValue)
    let obj = {
      id: store.currentPen.id,
      [propKey]: propValue
    }
    if (propKey === 'animateType') {
      obj.showDuration = getDuration(propValue)
      if (propValue === '') {
        obj.frames = null
      } else if (propValue === 'upDown') {
        obj.frames = [
          {
            y: -10,
            duration: 100
          },
          {
            y: 10,
            duration: 80
          },
          {
            y: -10,
            duration: 50
          },
          {
            y: 10,
            duration: 30
          },
          {
            y: 0,
            duration: 300
          }
        ]
      } else if (propValue === 'leftRight') {
        obj.frames = [
          {
            x: -10,
            duration: 100
          },
          {
            x: 10,
            duration: 80
          },
          {
            x: -10,
            duration: 50
          },
          {
            x: 10,
            duration: 30
          },
          {
            x: 0,
            duration: 300
          }
        ]
      } else if (propValue === 'heart') {
        obj.frames = [
          {
            scale: 1.1,
            duration: 100
          },
          {
            scale: 1,
            duration: 400
          }
        ]
      } else if (propValue === 'success') {
        obj.frames = [
          {
            background: '#389e0d22',
            color: '#237804',
            duration: 500
          }
        ]
      } else if (propValue === 'warning') {
        obj.frames = [
          {
            color: '#fa8c16',
            lineDash: [10, 10],
            duration: 300
          },
          {
            color: '#fa8c16',
            duration: 500
          },
          {
            color: '#fa8c16',
            lineDash: [10, 10],
            duration: 300
          }
        ]
      } else if (propValue === 'error') {
        obj.frames = [
          {
            color: '#cf1322',
            background: '#cf132222',
            duration: 100
          }
        ]
      } else if (propValue === 'show') {
        obj.frames = [
          {
            color: '#fa541c',
            rotate: -10,
            duration: 100
          },
          {
            color: '#fa541c',
            rotate: 10,
            duration: 100
          },
          {
            color: '#fa541c',
            rotate: 0,
            duration: 100
          }
        ]
      } else if (propValue === 'rotate') {
        obj.frames = [
          {
            rotate: 360,
            duration: 1000
          }
        ]
      }
      activeDuration.value = obj.showDuration
    }
    window.meta2d && window.meta2d.canvas && window.meta2d.setValue(obj, { history: true })
    window.meta2d && window.meta2d.canvas && window.meta2d.render()
  }
  const lineTypeSelect = ref<ComponentPublicInstance | null>(null)
  function handleChangePenLineType(val: string) {
    console.log('set pen lineType', val)
    const strokeType = lineStrokeOptions.find((option) => {
      return option.value === val
    })
    lineTypeSelect.value?.$el.children[0].children[0].setAttribute(
      'style',
      `background: url(${strokeType?.svg}) no-repeat;
            background-size: 80%;
            background-position: center;
          `
    )
    window.meta2d &&
      window.meta2d.setValue({ id: store.currentPen.id, animateLineDash: val.split(',') }, { history: true })
  }
  function startAnimate() {
    window.meta2d && window.meta2d.canvas && window.meta2d.startAnimate(store.currentPen.id)
  }
  function pauseAnimate() {
    window.meta2d && window.meta2d.canvas && window.meta2d.pauseAnimate(store.currentPen.id)
  }
  function stopAnimate() {
    window.meta2d && window.meta2d.canvas && window.meta2d.stopAnimate(store.currentPen.id)
  }
  function getDuration(value: string) {
    if (value === '') {
      return 0
    } else if (value === 'error') {
      return 100
    } else if (value === 'show') {
      return 300
    } else if (value === 'heart' || value === 'success') {
      return 500
    } else if (value === 'upDown' || value === 'leftRight') {
      return 560
    } else if (value === 'rotate') {
      return 1000
    } else if (value === 'warning') {
      return 1100
    }
  }
</script>
